<script setup>

import Game from "@/components/game.vue";
import Info from "@/components/info.vue";
import {reactive, ref, watch} from "vue";
//下一个方块
const next_fk = reactive([
      [0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0]
    ]),
    now_fk = reactive([
      [0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 0]
    ]);

//分数
let score = ref(0);

let speed = ref("低速");

//游戏状态 0未开始 1 游戏中 2 游戏暂停 -1 游戏结束
let state = ref(0);


watch(score, (newValue) => {
  if (newValue > 15) {
    speed.value = "高速";
  } else if (newValue > 5) {
    speed.value = "中速";
  }
});

//开始游戏
function startGame() {
  let oldState = state.value;
  state.value = 1;
  //新游戏
  if (oldState < 1) {
    //初始化变量
    score.value = 0;
    speed.value = "低速";
    next_fk.forEach((tr, x) => tr.forEach((td, y) => next_fk[x][y] = 0));
    now_fk.forEach((tr, x) => tr.forEach((td, y) => now_fk[x][y] = 0));
    randomFk();
  } else {

  }

}

function randomFk(s) {
  if (s) {
    score.value += s;
  }

  //初始化
  next_fk.forEach((tr, x) => tr.forEach((td, y) => {
    now_fk[x][y] = td;
    next_fk[x][y] = 0;
  }));

  let yx = [], kx = [];

  for (let i = 0; i < 4; i++) {
    let x, y;
    if (kx.length <= 0) {
      x = Math.floor(Math.random() * 4);
      y = Math.floor(Math.random() * 4);
    } else {
      let kx_l = kx.length;
      let xz_i = Math.floor(Math.random() * kx_l);
      [x, y] = kx[xz_i];
      kx.splice(xz_i, 1);
    }

    yx.push([x, y]);

    let xg = [];

    let ycz = function () {
      if (!yx.find(k => k.toString() === xg.toString()) && !kx.find(k => k.toString() === xg.toString())) {
        kx.push(xg);
      }
    }

    if (x - 1 > 0) {
      xg = [x - 1, y];
      ycz();
    }
    if (x + 1 < 4) {
      xg = [x + 1, y];
      ycz();
    }
    if (y - 1 > 0) {
      xg = [x, y - 1];
      ycz();
    }
    if (y + 1 < 4) {
      xg = [x, y + 1];
      ycz();
    }
  }

  yx.forEach(([x, y]) => next_fk[x][y] = getShapeIndex(yx.concat()));

  if (now_fk.every(tr => tr.every(td => td === 0))) {
    randomFk();
  }

  while (now_fk.every((tr, x) => tr.every((td, y) => td === next_fk[x][y]))) {
    randomFk();
  }

}

function getShapeIndex(xfx) {
  return ["O", "I", "J", "L", "T", "Z", "S"].indexOf(getShape(xfx)) + 1;
}

//获取方块形状
function getShape(xfx) {
  let xl = [], yl = [];
  //先排个序,先根据X坐标来排序，如果X相同，那就使用Y来排序
  xfx.sort((a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]).forEach(([x, y]) => {
    xl.push(x);
    yl.push(y);
  });

  //判断O型
  if (xl[3] - xl[0] === yl[3] - yl[0] && xl[0] === xl[1] && xl[2] === xl[3]) {
    return "O";
  }

  //判断I型
  if (xl[3] - xl[0] === 3 || yl[3] - yl[0] === 3) {
    return "I";
  }

  //判断L T J 型 ，共同点是在 X 轴 或者 Y 轴上都有三个相同坐标的点

  /**
   * X轴 XXXY型 xl[3] > xl[2]
   * 111  111  111
   * 1     1     1
   */
  if (xl[0] === xl[1] && xl[1] === xl[2] && xl[3] > xl[2]) {
    if (yl[3] === yl[0]) {
      return "L";
    } else if (yl[3] === yl[1]) {
      return "T";
    } else if (yl[3] === yl[2]) {
      return "J";
    }
  }

  /**
   * X轴 XXXY型 xl[1] > xl[0]
   * 1     1     1
   * 111  111  111

   */
  if (xl[1] === xl[2] && xl[2] === xl[3] && xl[1] > xl[0]) {
    if (yl[0] === yl[1]) {
      return "J";
    } else if (yl[0] === yl[2]) {
      return "T";
    } else if (yl[0] === yl[3]) {
      return "L";
    }
  }

  /**
   * Y轴 YYYX型 nyl[3] > nyl[2]
   * 11     1     1
   * 1      11    1
   * 1      1     11
   */
  let nyl = yl.concat().sort();
  if (nyl[0] === nyl[1] && nyl[1] === nyl[2] && nyl[3] > nyl[2]) {
    if (xl[0] === xl[1]) {
      return "J";
    } else if (xl[1] === xl[2]) {
      return "T";
    } else if (xl[2] === xl[3]) {
      return "L";
    }
  }

  /**
   * Y轴 YYYX型 nyl[1] > nyl[0]
   *  11      1     1
   *   1     11     1
   *   1      1    11
   */
  if (nyl[1] === nyl[2] && nyl[2] === nyl[3] && nyl[1] > nyl[0]) {
    if (xl[0] === xl[1]) {
      return "L";
    } else if (xl[1] === xl[2]) {
      return "T";
    } else if (xl[2] === xl[3]) {
      return "J";
    }
  }

  //判断Z S
  /**
   * X轴 XXYY型
   * 11      11
   *  11    11
   */
  if (xl[0] === xl[1] && xl[2] === xl[3]) {
    if (yl[1] === yl[2]) {
      return "Z";
    } else if (yl[3] === yl[0]) {
      return "S";
    }
  }

  //判断Z S
  /**
   * Y轴 XXYY型
   *  1      1
   *  11    11
   *   1    1
   */
  if (nyl[0] === nyl[1] && nyl[2] === nyl[3]) {
    if (xl[1] === xl[2] && yl[0] === yl[1]) {
      return "S";
    } else if (xl[1] === xl[2] && yl[0] === yl[2]) {
      return "Z";
    }
  }

}

</script>

<template>
  <main>
    <game v-bind="{now_fk,state,speed}" @createNewFk="randomFk" @gameOver="state = -1"></game>
    <info v-bind="{score,next_fk,state,speed}" @pauseGame="state = 2"></info>

    <div class="zzc" v-if="state !== 1">
      <button :class="`btn-${state}`" type="button" @click="startGame">
        <span v-if="state === 0">开始</span>
        <span v-if="state === 2">继续</span>
        <span v-if="state < 0">重新</span>
        游戏
      </button>
      <h4 v-if="state === 2 || state < 0">
        <span>您的游戏得分：</span><span>{{ score }}</span>
      </h4>
    </div>

  </main>
  <div>
    <!--    <button type="button" @click="()=>{ now_fk.forEach((tr, x) => tr.forEach((td, y) => {
        next_fk[x][y] = td;
      }))}">重置下一个方块跟当前方块相同
        </button>-->
  </div>
</template>

<style>
body, table, button {
  caret-color: transparent;
}

main {
  display: flex;
  padding: 20px;
}

.zzc {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  text-align: center;
  padding-top: 40%;
  background-color: rgb(255 255 255 / 5%);
}

.zzc button {
  padding: 6px 12px;
  font-size: large;
  border: none;
  cursor: pointer;
  color: #fff;
}

.zzc button.btn-0,
.zzc button.btn--1 {
  background-color: royalblue;
}

.zzc button.btn-2 {
  background-color: darkolivegreen;
}

.zzc h4 {
  margin-top: 15px;
  font-size: xx-large;
  color: yellowgreen;
}


table {
  border-collapse: collapse;
}

table td {
  width: 35px;
  height: 35px;
  text-align: center;
}

/**
"O", "I", "J", "L", "T", "Z", "S"
 1    2    3    4    5    6    7
 黄   蓝   粉    橙   紫    绿   红
 */
table td.check1 {
  background-color: yellow;
  border-color: yellow;
}

table td.check2 {
  background-color: blue;
  border-color: blue;
}

table td.check3 {
  background-color: pink;
  border-color: pink;
}

table td.check4 {
  background-color: orange;
  border-color: orange;
}

table td.check5 {
  background-color: purple;
  border-color: purple;
}

table td.check6 {
  background-color: green;
  border-color: green;
}

table td.check7 {
  background-color: red;
  border-color: red;
}

table td[class^='check']::after {
  content: '';
  background-color: rgb(255 255 255 / 5%);
  box-shadow: 1px -1px 4px 0 rgb(0 0 0 / 70%);
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  right: 4px;
}

</style>
